package easytasks.ui;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import easytasks.data.DataManager;
import easytasks.data.DataSetup;
import easytasks.data.Task;
import easytasks.data.TaskCategory;
import easytasks.logic.DateFormatter;
import easytasks.logic.DateFormatter.DateAsStringType;
import easytasks.main.R;
import easytasks.settings.Settings;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.DatePickerDialog.OnDateSetListener;
import android.app.TimePickerDialog;
import android.app.TimePickerDialog.OnTimeSetListener;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.TimePicker;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.TextView;

public class EditTaskActivity extends Activity
{
	public static final int SUBACTIVITY_REQUEST_CODE = 0;
	public static final int SUBACTIVITY_RESULT_CATEGORIES_OK_CODE = 1;
	public static final int SUBACTIVITY_RESULT_CANCEL_CODE = 2;
	
	private Task taskToEdit = null;
	
	private Date selectedDate = null;
	private List<TaskCategory> selectedCategories = null;
	
	private Button butOk;
	private Button butCancel;
	
	private EditText editTitle;
	private EditText editDescription;
	private TextView textDate;
	private ImageButton butEditDate;
	private CheckBox checkIgnoreTime;
	private ImageButton butEditTime;
	private TextView textCategories;
	private ImageButton butEditCategories;
	
	private DataSetup dataInit;
	private DataManager dataManager;
	
	@Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.edittask);
        
        dataInit = new DataSetup(this);
        dataManager = new DataManager(dataInit, PreferenceManager.getDefaultSharedPreferences(this));
        
        editTitle = (EditText)findViewById(R.id.editEditTaskTitle);
        editDescription = (EditText)findViewById(R.id.editEditTaskDescription);
        textDate = (TextView)findViewById(R.id.textEditTaskDate);
        textCategories = (TextView)findViewById(R.id.textEditTaskCategories);
		butOk = (Button)findViewById(R.id.butEditTaskOk);
		butCancel = (Button)findViewById(R.id.butEditTaskCancel);
		butEditDate = (ImageButton)findViewById(R.id.butEditTaskDate);
		checkIgnoreTime = (CheckBox)findViewById(R.id.checkEditTaskIgnoreTime);
		butEditTime = (ImageButton)findViewById(R.id.butEditTaskTime);
		butEditCategories = (ImageButton)findViewById(R.id.butEditTaskCategories);
		
		editTitle.addTextChangedListener(new TextWatcher() {			
			public void onTextChanged(CharSequence s, int start, int before, int count) {}
			public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
			public void afterTextChanged(Editable s) 
			{
				checkRequiredData();
			}
		});
		
		butOk.setOnClickListener(new OnClickListener() {
			public void onClick(View v)
			{
				if (taskToEdit == null) // New task mode
				{
					Task newTask = new Task(editTitle.getText().toString(), selectedDate, checkIgnoreTime.isChecked(), editDescription.getText().toString(), selectedCategories, false);
					dataManager.addTask(newTask);
				}
				else // Edit existing task mode
				{
					Task newTask = new Task(editTitle.getText().toString(), selectedDate, checkIgnoreTime.isChecked(), editDescription.getText().toString(), selectedCategories, taskToEdit.isDone());
					dataManager.updateTask(taskToEdit, newTask);
				}
				
				finish();
			}
		});
		
        butCancel.setOnClickListener(new OnClickListener() {
			public void onClick(View v) 
			{
				finish();
			}
		});
        
        butEditDate.setOnClickListener(new OnClickListener() {
			public void onClick(View v) 
			{
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(selectedDate);
				
				DatePickerDialog dialog = new DatePickerDialog(EditTaskActivity.this, new OnDateSetListener() {
					public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth)
					{
						Calendar calendar = Calendar.getInstance();
						calendar.setTime(selectedDate);
						calendar.set(Calendar.YEAR, year);
						calendar.set(Calendar.MONTH, monthOfYear);
						calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
						selectedDate = calendar.getTime();
						refresh();
					}
				}, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
				
				dialog.show();
			}
		});
        
        checkIgnoreTime.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
			{
				checkIgnoreTime();
				refreshDate();
			}
		});
        
        butEditTime.setOnClickListener(new OnClickListener() {
			public void onClick(View v)
			{
				Calendar calendar = Calendar.getInstance();
				calendar.setTime(selectedDate);
				
				TimePickerDialog dialog = new TimePickerDialog(EditTaskActivity.this, new OnTimeSetListener() {
					public void onTimeSet(TimePicker view, int hourOfDay, int minute)
					{
						Calendar calendar = Calendar.getInstance();
						calendar.setTime(selectedDate);
						calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
						calendar.set(Calendar.MINUTE, minute);
						selectedDate = calendar.getTime();
						refresh();
					}
				}, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), true);
				
				dialog.show();
			}
		});
        
        butEditCategories.setOnClickListener(new OnClickListener() {
			public void onClick(View v) 
			{
				Intent intent = new Intent(EditTaskActivity.this, EditTaskCategoriesActivity.class);
				intent.putExtra("categories", (Serializable) selectedCategories); // Categories to edit
				startActivityForResult(intent, SUBACTIVITY_REQUEST_CODE);
			}
		});
        
        Serializable receivedTask = getIntent().getSerializableExtra("task");
        if (receivedTask == null) // New task mode
        {
        	loadDefaultTaskData();
        }
        else // Edit existing task mode
		{
        	taskToEdit = (Task)receivedTask;
			setTitle(R.string.edittask_title_edittask);
			loadTaskToEditData();
		}
        
        checkRequiredData();
        checkIgnoreTime();
    }
	
	@Override
    public void onResume()
    {
    	super.onResume();
    	refresh();
    }
	
	private void loadDefaultTaskData()
	{
		editTitle.setText("");
		editDescription.setText("");
		
		selectedCategories = new ArrayList<TaskCategory>();
		
		Calendar calendar = Calendar.getInstance();
		calendar.clear(Calendar.HOUR);
		calendar.clear(Calendar.HOUR_OF_DAY);
		calendar.clear(Calendar.MINUTE);
		calendar.clear(Calendar.SECOND);
		calendar.clear(Calendar.MILLISECOND);
		
		String view = getIntent().getStringExtra("view");
		if (view != null)
		{
			if (view.equals("tomorrow"))
			{
				calendar.add(Calendar.DAY_OF_MONTH, 1);
				selectedDate = calendar.getTime(); // Tomorrow
			}
			else if (view.equals("next-week"))
			{
				SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
				String firstDay = sharedPref.getString(Settings.FIRST_DAY_OF_WEEK_KEY, Settings.FIRST_DAY_OF_WEEK_DEFAULT_VALUE);
				int firstDayOfWeek;
				
				if (firstDay.equals("mon")) firstDayOfWeek = Calendar.MONDAY;
				else if (firstDay.equals("tue")) firstDayOfWeek = Calendar.TUESDAY;
				else if (firstDay.equals("wed")) firstDayOfWeek = Calendar.WEDNESDAY;
				else if (firstDay.equals("thu")) firstDayOfWeek = Calendar.THURSDAY;
				else if (firstDay.equals("fri")) firstDayOfWeek = Calendar.FRIDAY;
				else if (firstDay.equals("sat")) firstDayOfWeek = Calendar.SATURDAY;
				else firstDayOfWeek = Calendar.SUNDAY;
				
				int diff = calendar.get(Calendar.DAY_OF_WEEK) - firstDayOfWeek;
				int sum;
				
				if (diff < 0) sum = - diff;
				else sum = - diff + 7;
				
				calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + sum);
				selectedDate = calendar.getTime(); // First day of next week
				
			}
			else if (view.equals("by-category"))
			{
				selectedDate = calendar.getTime(); // Today				
				Serializable taskCategoryReceived = getIntent().getSerializableExtra("category");
				
				if (taskCategoryReceived != null && taskCategoryReceived instanceof TaskCategory)
	            {
	            	TaskCategory taskCategory = (TaskCategory)taskCategoryReceived;
	            	selectedCategories.add(taskCategory);
	            }
			}
			else
			{
				selectedDate = calendar.getTime(); // Today
			}
		}
		else
		{
			selectedDate = calendar.getTime(); // Today
		}
		
		checkIgnoreTime.setChecked(true);
	}
	
	private void loadTaskToEditData()
	{
		editTitle.setText(taskToEdit.getTitle());
		editDescription.setText(taskToEdit.getDescription());
		selectedDate = taskToEdit.getTime();
		checkIgnoreTime.setChecked(taskToEdit.getIgnoreHour());
		selectedCategories = taskToEdit.getCategories();
	}
	
	private void refresh()
	{
		refreshDate();
		refreshCategories();
	}
	
	private void refreshDate()
	{
		textDate.setText((new DateFormatter(this)).getTimeAsString(selectedDate, DateAsStringType.WEEKDAY_AND_SHORTMONTHANDHOUR, checkIgnoreTime.isChecked()));
	}
	
	private void refreshCategories()
	{
		String text = "";
		int categoryCount = selectedCategories.size();
		
		for (int i = 0; i < categoryCount; i++)
		{
			text += selectedCategories.get(i).getName();
			if (i < (categoryCount - 1)) text += ", ";
		}
		
		textCategories.setText(text);
	}
	
	private void checkRequiredData()
	{
		butOk.setEnabled(!editTitle.getText().toString().trim().equals(""));
	}
	
	private void checkIgnoreTime()
	{
		boolean checked = checkIgnoreTime.isChecked();
		butEditTime.setEnabled(!checked);
		
		if (checked)
		{
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(selectedDate);
			
			calendar.clear(Calendar.HOUR);
			calendar.clear(Calendar.HOUR_OF_DAY);
			calendar.clear(Calendar.MINUTE);
			calendar.clear(Calendar.SECOND);
			calendar.clear(Calendar.MILLISECOND);
			
			selectedDate = calendar.getTime();
		}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		super.onActivityResult(requestCode, resultCode, data);
		
		if (resultCode == SUBACTIVITY_RESULT_CATEGORIES_OK_CODE) selectedCategories = (List<TaskCategory>) data.getSerializableExtra("categories");		
		refresh();
	}
}
